package com.my.spring.framework.aop;

import com.my.spring.framework.aop.intercept.MyMethodInvocation;
import com.my.spring.framework.aop.support.MyAdvisedSupport;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;

public class MyCglibAopProxy implements MyAopProxy, MethodInterceptor {
    private MyAdvisedSupport advised;
    public MyCglibAopProxy(MyAdvisedSupport advised) {
        this.advised = advised;
    }

    @Override
    public Object getProxy() {
        return getProxy(advised.getTargetClass().getClassLoader());
    }

    @Override
    public Object getProxy(ClassLoader classLoader) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(advised.getTargetClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        List<Object> interceptorsAndDynamicMethodMatchers = advised.getInterceptorsAndDynamicInterceptionAdvice(method, advised.getTargetClass());
        MyMethodInvocation invocation = new MyMethodInvocation(methodProxy, advised.getTarget(), method, objects, advised.getTargetClass(), interceptorsAndDynamicMethodMatchers);
        return invocation.proceed();
    }
}
